package com.mhs.map;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;

import android.view.View;
import android.view.View.OnClickListener;

import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;


import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;

import com.mhs.DTO.PlacemarkDTO;
import com.mhs.mhs_gui.R;
import com.mhs.mydialog.MyDialogListner;
import com.mhs.services.PublicVariable;

public class GMap extends MapActivity {

	EditText editLocationSearchName;
	MapView mapView;
	MapController mc;
	ImageView imgLayersMap;
	MyLocationOverlay myLocationOverlay;
	// LocationManager locationManager;
	// MyOverlays itemizedoverlay;
	GeoPoint p;

	static final int PROGRESS_DIALOG = 0;
	ProgressDialog progressDialog;
	ProgressThread progressThread;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.googlemap);
		List<PlacemarkDTO> lstPlacemarkDTO = new ArrayList<PlacemarkDTO>();
		lstPlacemarkDTO = PublicVariable.getLstPlaceMark();
		// clear PublicVariable
		//PublicVariable.clearListPlaceMark(PublicVariable.getLstPlaceMark());
		if (isNetworkAvailable()) {

			showDialog(PROGRESS_DIALOG);

			mapView = (MapView) findViewById(R.id.MapView);
			mapView.setBuiltInZoomControls(true);
			mapView.setTraffic(false);
			mapView.setSatellite(false);
			mc = mapView.getController();
			mc.setZoom(14);

			// locationManager = (LocationManager)
			// getSystemService(Context.LOCATION_SERVICE);
			// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
			// 0,
			// 0, new GeoUpdateHandler());

			Drawable drawable = this.getResources().getDrawable(
					R.drawable.normal_marker);
			drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
					drawable.getIntrinsicHeight());

			myLocationOverlay = new MyLocationOverlay(this, mapView);
			mapView.getOverlays().add(myLocationOverlay);

			myLocationOverlay.runOnFirstFix(new Runnable() {
				public void run() {
					mapView.getController().animateTo(
							myLocationOverlay.getMyLocation());
				}
			});

			mapView.getOverlays().add(new SitesOverlay(drawable, lstPlacemarkDTO));
			// itemizedoverlay = new MyOverlays(this, drawable);
			// createMarker();
			mapView.invalidate();

			imgLayersMap = (ImageView) findViewById(R.id.imgLayersMap);
			imgLayersMap.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					AlertDialog diag = showDialogLayersMap(GMap.this);
					diag.setOnDismissListener(new OnDismissListener() {

						public void onDismiss(DialogInterface dialog) {
							loadMyMap();
						}
					});
					diag.show();
				}
			});

			editLocationSearchName = (EditText) findViewById(R.id.edtLocationSearchName);
			editLocationSearchName.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					Intent intentSearchLocation = new Intent(GMap.this,
							SearchLocation.class);
					startActivity(intentSearchLocation);
				}
			});
		} else {
			MyDialogListner.ShowMessageAlert(this,
					"Yêu cầu kết nối mạng cho ứng dụng!");
			return;
		}
	}

	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case PROGRESS_DIALOG:
			progressDialog = new ProgressDialog(GMap.this);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			progressDialog.setMessage("Loading map...");
			return progressDialog;
		default:
			return null;
		}
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
		case PROGRESS_DIALOG:
			progressDialog.setProgress(0);
			progressThread = new ProgressThread(handler);
			progressThread.start();
		}
	}

	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			int total = msg.arg1;
			progressDialog.setProgress(total);
			if (total >= 100) {
				dismissDialog(PROGRESS_DIALOG);
				progressThread.setState(ProgressThread.STATE_DONE);
			}
		}
	};

	public class ProgressThread extends Thread {
		Handler mHandler;
		final static int STATE_DONE = 0;
		final static int STATE_RUNNING = 1;
		int mState;
		int total;

		ProgressThread(Handler h) {
			mHandler = h;
		}

		public void run() {
			mState = STATE_RUNNING;
			total = 0;
			while (mState == STATE_RUNNING) {
				try {
					Thread.sleep(150);
					// tam thoi send toa do cua ng dung bang tay:
					// double lat = Double.parseDouble("10.835277");
					// double lon = Double.parseDouble("106.662707");
					// Intent serviceGetHospitalNear = new Intent(GMap.this,
					// GetHospitalNear.class);
					// Bundle myData = new Bundle();
					// myData.putDouble("latitude", lat);
					// myData.putDouble("longitude", lon);
					// serviceGetHospitalNear.putExtras(myData);
					// //PendingIntent.getService(GMap.this, 0,
					// serviceGetHospitalNear, 0);
					// startService(serviceGetHospitalNear);
					// requestToGetHospitalNear(lat, lon);
				} catch (InterruptedException e) {
					Log.e("ERROR", "Thread Interrupted");
				} catch (Exception e) {

				}
				Message msg = mHandler.obtainMessage();
				msg.arg1 = total;
				mHandler.sendMessage(msg);
				total++;
			}
		}

		/*
		 * sets the current state for the thread, used to stop the thread
		 */
		public void setState(int state) {
			mState = state;
		}
	}

	public void loadMyMap() {
		mapView.setTraffic(false);
		mapView.setSatellite(false);
	}

	public AlertDialog showDialogLayersMap(Context context) {
		final CharSequence[] items = { "Bình thường", "Vệ tinh", "Giao thông" };

		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("Lớp");
		builder.setItems(items, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				switch (item) {
				case 0:
					// binh thuong
					mapView.setTraffic(false);
					mapView.setSatellite(false);
					// mapView.postInvalidateDelayed(2000);
					break;
				case 1:
					mapView.setSatellite(true);
					// mapView.postInvalidateDelayed(2000);
					break;
				case 2:
					mapView.setTraffic(true);
					// mapView.postInvalidateDelayed(2000);
					break;
				default:
					break;
				}
			}
		});
		builder.setNegativeButton("Hủy", null);
		AlertDialog alert = builder.create();
		return alert;
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	protected boolean isLocationDisplayed() {
		return true;
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	@Override
	protected void onResume() {
		super.onResume();
		myLocationOverlay.enableCompass();
		myLocationOverlay.enableMyLocation();
	}

	@Override
	protected void onPause() {
		super.onPause();
		myLocationOverlay.disableCompass();
		myLocationOverlay.disableMyLocation();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		MapController mc = mapView.getController();
		switch (keyCode) {
		case KeyEvent.KEYCODE_I:
			mc.zoomIn();
			break;
		case KeyEvent.KEYCODE_O:
			mc.zoomOut();
			break;
		}
		return super.onKeyDown(keyCode, event);
	}

	// private void createMarker() {
	// GeoPoint p = mapView.getMapCenter();
	// OverlayItem overlayitem = new OverlayItem(p, "", "");
	// itemizedoverlay.addOverlay(overlayitem);
	// if (itemizedoverlay.size() > 0) {
	// mapView.getOverlays().add(itemizedoverlay);
	// }
	// }

	public static GeoPoint getPoint(double lat, double lon) {
		return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
	}

	public class GeoUpdateHandler implements LocationListener {

		public void onLocationChanged(Location location) {
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			GeoPoint point = new GeoPoint(lat, lng);
			// createMarker();
			mc.animateTo(point); // mapController.setCenter(point);

		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	public boolean isNetworkAvailable() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = cm.getActiveNetworkInfo();
		// if no network is available networkInfo will be null
		// otherwise check if we are connected
		if (networkInfo != null && networkInfo.isConnected()) {
			return true;
		}
		return false;
	}
	
	private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
		
		public List<OverlayItem> items = new ArrayList<OverlayItem>();
		private Drawable marker = null;
		
		private long lastTouchTimeDown = -1;
		private long lastTouchTimeUp = -1;
		List<PlacemarkDTO> lstPlacemarkDTO = new ArrayList<PlacemarkDTO>();
		
		public SitesOverlay(Drawable defaultMarker) {
			super(defaultMarker);
			this.marker = defaultMarker;	
			populate();
		}

		public SitesOverlay(Drawable drawable, List<PlacemarkDTO> lstPlacemarkDTOSrc) {
			super(drawable);
			this.marker = drawable;
			lstPlacemarkDTO = lstPlacemarkDTOSrc;
			for(int i = 0;i < lstPlacemarkDTO.size();i++){
				PlacemarkDTO pmDTO = lstPlacemarkDTO.get(i);
				double lat = Double.parseDouble(pmDTO.getLatitude());
				double lon = Double.parseDouble(pmDTO.getLongitude());
				GeoPoint geoPointBenhVien = GMap.getPoint(lat, lon);
				OverlayItem ovItemBenhVien = new OverlayItem(geoPointBenhVien,
						pmDTO.getName(), pmDTO.getAddress());
				// add marker vo:
				items.add(ovItemBenhVien);		
			}
			populate();
		}

		@Override
		protected OverlayItem createItem(int i) {
			return (items.get(i));
		}

		@Override
		public int size() {
			return (items.size());
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			super.draw(canvas, mapView, shadow);

			boundCenterBottom(marker);
		}
		
		protected boolean onTap(int i) {
			//if time Difference between lastTouchTimeUp & lastTouchTimeDown is:
			// > 1500 millisec. it was a LONG TAP
			// < 1500 just a NORMAL tap
			// on LONG TAPs we may want to show a dialog box with additional 
			// data about item i-th such as pictures, links to web-sites, ???, etc. 
			//---------------------------------------------------------------------
			String text = "NORMAL TAP";
			long pressTotalTime = lastTouchTimeUp - lastTouchTimeDown;
			if (pressTotalTime > 1500) {
				text = "LONG TAP";
			}
			
			Toast.makeText(GMap.this,
					items.get(i).getTitle() + "\n" +
					items.get(i).getSnippet(), Toast.LENGTH_SHORT).show();

			return (true);
		}
		
		// TODO implement longPress actions (such as dialog box showing
		//      pictures, links, ???, of selected point.
		public boolean onTouchEvent(MotionEvent event, MapView mapView) {
			//remember the initial time the user touches the screen
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				lastTouchTimeDown = event.getDownTime();
				lastTouchTimeDown = System.currentTimeMillis();
			}
			if (event.getAction() == MotionEvent.ACTION_UP) {
				lastTouchTimeUp = System.currentTimeMillis();
			}			
			return super.onTouchEvent(event, mapView);
		}
	}
}
